Skip to content

Upgrade Frida to 17.16.1 migrate to Rust edition 2024, and expand Gum API coverage#242

Closed
kkuehl wants to merge 56 commits into
frida:mainfrom
kkuehl:kkuehl/frida-rust-updates
Closed

Upgrade Frida to 17.16.1 migrate to Rust edition 2024, and expand Gum API coverage#242
kkuehl wants to merge 56 commits into
frida:mainfrom
kkuehl:kkuehl/frida-rust-updates

Conversation

@kkuehl

@kkuehl kkuehl commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Upgrade Frida to 17.15.3, migrate to Rust edition 2024, and expand Gum API coverage

Brings the bindings current with Frida 17.15.3, migrates the workspace to Rust edition 2024, fixes soundness issues found during C API audit, and adds bindings for APIs introduced in Frida 17.10–17.15.

Frida & Toolchain

  • Upgrade Frida: 17.9.5 → 17.15.3 (devkit + bindings)
  • Rust edition 2024: unsafe extern blocks, explicit unsafe {} in unsafe fns, match ergonomics
  • reqwest 0.12 → 0.13: unified TLS feature naming (rustls vs rustls-tls)

New API Bindings (17.10–17.15)

  • ControlFlowGraph: construction, dominator queries, block bounds/successors/predecessors, instruction lookup
  • ElfModule (17.15.0): from_file/from_memory, property accessors (pointer size, byte order, OS ABI, mapped size, addresses, entrypoint, interpreter, source path), enumerate_dynamic_entries for ELF .dynamic section iteration (Linux/Android/FreeBSD only)
  • Process: find_function_range (works on stripped binaries), get_parameters() (argv via Variant::StringList)
  • Interceptor: flush_function/flush_listener, attach_with_options + AttachOptions builder
  • UnwindBroker: obtain + provider/translator registration
  • Memory: mprotect/try_mprotect, clear_cache, ensure_code_readable, try_alloc_n_pages_near, patch_code_pages
  • Misc: DebugSymbol::load_symbols, Exceptor::exception_details_to_string, CodeAllocator::alloc_deflector, InvocationContext listener-data getters

Soundness & Correctness Fixes

  • ModuleMap::new_with_filter: fix use-after-free — filter is now owned ('static + GDestroyNotify) instead of dangling temporary
  • range_details: add missing PageProtection::WriteExecute variant; stop panicking on unexpected protection bits in FFI callbacks
  • Process::current_dir: free transfer-full string (was leaking)
  • module/process enumerators: fix &T as *mut aliasing UB
  • Exceptor::add: require Send (handlers run on faulting thread)
  • MatchPattern::from_string: return None instead of panicking on interior-NUL
  • Writer wrappers: void C functions now return () instead of fake bool

Cross-Platform Fixes

  • unsafe extern: all extern "C" blocks now unsafe extern "C" (aarch64/x86_64 relocators, Linux/FreeBSD process module)
  • Enum signedness: cast with as _ for bindgen i32/u32 platform variance (MSVC vs clang)
  • GLib symbol prefixing: _frida_g_* on Linux/FreeBSD/iOS devkits, bare g_* on Windows/macOS — unified via glib_compat module
  • gchar signedness: CString/CStr pointers use .cast() for clang i8 vs MSVC i8/u8 variance

kkuehl added 6 commits June 11, 2026 09:07
Update frida-rust bindings to support Frida 17.11.0 API changes:

- Update FRIDA_VERSION files to 17.11.0
- Remove deprecated Stalker::enable_unwind_hooking() method
  (gum_stalker_activate_experimental_unwind_support was removed)
- Update Interceptor::replace() to use new 5-parameter API with GumReplaceOptions
- Update Interceptor::replace_fast() to use new 5-parameter API with GumInterceptorOptions

The new interceptor options provide fine-grained control over code patching:
- scratch_register: Register for temporary operations (-1 for auto)
- scenario: Interceptor scenario (DEFAULT/EXCLUSIVE)
- relocation_policy: Code relocation strategy (DEFAULT/CRITICAL)
- write_redirect: Custom memory write callback (NULL for default)
- redirect_space_hint: Space hint for redirects (0 for auto)

Default values maintain backward-compatible behavior.
- Update FRIDA_VERSION files to 17.13.0
- Add new API bindings: ApiResolver, Cloak, CodeAllocator, CodeSegment, Exceptor, Memory, Query, Registry, SymbolUtil, TLS
- Update existing bindings for compatibility
- Update examples for new API patterns
- Upgrade FRIDA_VERSION from 17.11.0 to 17.12.0
- Add new API bindings: ApiResolver, Cloak, CodeAllocator, CodeSegment, Exceptor, Memory, Query, Registry, SymbolUtil, TLS
- Update existing bindings for compatibility
- Update examples for new API patterns
- Note: 17.13.0 upgrade pending release of devkit binaries
…ndings

Quality/soundness fixes (verified against frida-gum C source):
- module_map: fix use-after-free in new_with_filter (filter was a dangling
  temporary Box with no destroy-notify, but Frida retains and re-invokes it on
  every update); now owns the closure by value + GDestroyNotify.
- range_details: add missing PageProtection::WriteExecute variant (value 6) and
  stop unwrap()-panicking on unexpected protection bits in an FFI callback.
- process: free the transfer-full string returned by g_get_current_dir.
- module/process: fix &T-as-*mut aliasing (UB) in enumerate_* callbacks.
- exceptor: require Send on the handler closure; document no auto-remove on drop.
- memory_range: MatchPattern::from_string returns None instead of panicking on
  interior-NUL input.
Several agent-flagged "bugs" were verified FALSE POSITIVES and left unchanged
(registry obtain() is transfer-none; gum_memory_read uses g_malloc; GumCodeSlice
refcount is atomic).

Frida + toolchain:
- Bump Frida 17.12.0 -> 17.13.0 (all FRIDA_VERSION files).
- Migrate workspace to edition 2024 (cargo fix --edition + manual unsafe-block
  fixes in feature-gated files the migration did not compile: invocation_listener,
  stalker/observer, stalker/event_sink, backtracer).

New API bindings (Frida 17.10-17.13):
- control_flow_graph.rs: GumControlFlowGraph (new/for_function, dominates,
  enumerate_dominating_sites, block queries, find_instruction_containing).
- Process::find_function_range (works on stripped binaries).
- Interceptor::flush_function / flush_listener.
- Interceptor::attach_with_options + AttachOptions builder.
- unwind_broker.rs: GumUnwindBroker obtain + provider/translator registration.
- frida core: Variant::StringList decodes GVariant "as" so the new argv process
  parameter surfaces via Process::get_parameters().

Wrap remaining pre-existing C API gaps:
- Memory::mprotect / try_mprotect / clear_cache / ensure_code_readable /
  try_alloc_n_pages_near / patch_code_pages.
- DebugSymbol::load_symbols.
- InvocationContext listener data getters (function / thread / invocation).
- Exceptor::exception_details_to_string.
- CodeAllocator::alloc_deflector (+ CodeDeflector type).

Verified (edition 2024, Frida 17.13.0): cargo build (all gum features), clippy
-D warnings (gum all-features + frida + frida-sys), cargo fmt --check, and
cargo test -p frida-gum (10 passed) all clean.
The instruction-writer wrappers for Gum C functions that are declared `void`
were fabricating `-> bool { ...; true }`, giving callers a meaningless success
signal. Change these inherent methods to return `()` to match the C ABI:

- x86_64: put_leave, put_ret, put_ret_imm, put_jmp_short_label,
  put_jmp_near_label, put_mov_reg_address, put_mov_reg_ptr_u32,
  put_mov_reg_ptr_reg, put_mov_reg_reg_ptr, put_push_u32, put_push_imm_ptr,
  put_nop, put_pushfx, put_popfx, put_pushax, put_popax.
- aarch64: put_call_address_with_arguments.

The InstructionWriter trait methods (put_bytes/put_label/put_branch_address/
put_nop/flush) are left returning bool: arm/arm64's underlying C functions
return gboolean, so the shared trait signature must stay. The x86 put_bytes impl
keeps its `true` fabrication only to satisfy that trait.

No callers consumed these return values. Verified: clippy -D warnings (gum
all-features), cargo fmt --check, cargo test -p frida-gum (10 passed).
@s1341

s1341 commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Wow. that's a big PR! Thanks!

in future, can I recommend that you submit a separate PR per issue, to keep things simpler?

Please address CI issues and I will review in depth.

@kkuehl
kkuehl marked this pull request as draft June 16, 2026 11:09
kkuehl added 15 commits June 16, 2026 07:18
…gnedness

- aarch64/relocator.rs + process.rs (linux/freebsd block): extern "C" -> unsafe
  extern "C" (edition 2024), in target-gated code the Windows build never
  compiled.
- Enum discriminants from bindgen constants now use `as _` so they work whether
  the platform's compiler types the C enum as i32 (MSVC) or u32 (clang):
  transformer MemoryAccess, process TeardownRequirement, exceptor ExceptorMode +
  ExceptionType, aarch64 IndexMode.
- thread WatchConditions bitflags backed by gum_sys::GumWatchConditions so
  bits() matches the FFI parameter on every platform.

Partial: macOS/Linux/iOS CI also surfaces GLib symbol naming (_frida_ prefix),
gchar pointer signedness, and jcc condition casts not yet addressed here.
Edition 2024 + platform differences the Windows/x86_64 build never exercised:

- unsafe extern: aarch64/relocator.rs (7 blocks) and process.rs linux/freebsd
  block were still plain `extern "C"`.
- Enum discriminant signedness: bindgen types C enums as i32 on MSVC but u32 on
  clang. Use `as _` so the cast is correct on both (and not flagged as a
  same-type cast on Windows): transformer MemoryAccess, process
  TeardownRequirement, exceptor ExceptorMode + ExceptionType, aarch64 IndexMode,
  and the jcc_short/jcc_near condition args in the x86 writer.
- thread WatchConditions bitflags backed by gum_sys::GumWatchConditions so
  bits() matches the FFI parameter on every platform.
- gchar pointer signedness: CString/CStr pointers passed to gum_* APIs typed as
  *const gchar (i8 on clang, differs from cstr_core's c_char) now use .cast()
  in api_resolver, symbol_util, debug_symbol.
- GLib symbol naming: g_free/g_error_free/g_array_free/g_ptr_array_* are
  _frida_-prefixed on the Linux/FreeBSD/iOS static devkits but bare g_* on
  Windows/macOS. Added a central cfg-gated glib_compat module (mirroring the
  existing _frida_g_get_*_dir handling) and routed all call sites through it.

Verified on Windows: clippy -D warnings (gum all-features) clean.
FRIDA_VERSION: bump 17.9.5 -> 17.14.0 across all FRIDA_VERSION files.

Edition 2024 (workspace Cargo.toml): `unsafe extern "C"` required for all
extern blocks; `unsafe_op_in_unsafe_fn` now deny-by-default requiring explicit
`unsafe {}` blocks inside unsafe fns; `ref` in let-else patterns removed.
Applied via `cargo fix --edition` where possible, remaining blockers fixed
manually first.

API changes for 17.13.0/17.14.0:
- gum_interceptor_replace/replace_fast: new options param added; pass null.
- gum_interceptor_attach: options param replaces separate listener_data arg.
- gum_stalker_activate_experimental_unwind_support: removed; drop wrapper.
- frida-build: fix redundant-reference lints in format!/println! macros.
- backtracer: fix double-reference in fuzzy_with_context.

Cross-platform (Linux/iOS devkits prefix GLib symbols with _frida_):
- variant.rs `ref` patterns updated for edition 2024 match ergonomics.
- process.rs Linux/FreeBSD extern block marked unsafe extern.
- aarch64/relocator.rs + x86_64/relocator.rs extern blocks marked unsafe.
- Add unsafe keyword to all extern "C" blocks in aarch64 relocator
- Update FRIDA_VERSION from 17.14.0 to 17.14.1 in both frida-sys and frida-gum-sys
- Fixes compilation errors with Rust edition 2024 requirement for unsafe extern blocks
Only uses reqwest::blocking::get with blocking + rustls-tls features,
all unchanged in 0.13. Lets downstream workspaces unify on reqwest 0.13
instead of compiling both 0.12 and 0.13.
Only uses reqwest::blocking::get with blocking + rustls-tls features,
all unchanged in 0.13. Lets downstream workspaces unify on reqwest 0.13
instead of compiling both 0.12 and 0.13.
…tls')

reqwest 0.13 renamed the rustls-tls feature to rustls; the old name no
longer resolves. Plain 'rustls' bundles a crypto provider (unlike
'rustls-no-provider').
…tls')

reqwest 0.13 renamed the rustls-tls feature to rustls; the old name no
longer resolves. Plain 'rustls' bundles a crypto provider (unlike
'rustls-no-provider').
Rust 2024 edition requires unsafe operations inside `unsafe fn` bodies
to be wrapped in explicit `unsafe {}` blocks. Add inner unsafe blocks to
create_cb, js_msg, and load_cb to satisfy unsafe_op_in_unsafe_fn lint.
…ition-2024

Keep frida-rust-updates Rust source (has more API bindings and CI fixes).
Take FRIDA_VERSION 17.15.0 from frida-17.13-edition-2024 branch.
New frida-gum/src/elf_module.rs wraps gum_elf_module_* APIs added in
17.15.0: ElfModule::from_file/from_memory constructors, property accessors
(pointer_size, byte_order, os_abi_version, mapped_size, base/preferred
address, entrypoint, interpreter, source_path), and
enumerate_dynamic_entries/dynamic_entries for iterating ELF .dynamic section.
Linux/Android/FreeBSD only (cfg-guarded against Windows and macOS/iOS).
@kkuehl kkuehl changed the title Update frida-rust to 17.13.0 Update frida-rust to 17.15.1 Jun 21, 2026
@kkuehl kkuehl changed the title Update frida-rust to 17.15.1 Upgrade Frida to 17.15.3, migrate to Rust edition 2024, and expand Gum API coverage Jun 25, 2026
@kkuehl
kkuehl force-pushed the kkuehl/frida-rust-updates branch from bbc496c to 0574dc9 Compare July 7, 2026 14:57
Merge upstream/main to resolve PR frida#242 conflicts and bring the branch
into mergeable state.

Key changes:
- Resolved 15 file conflicts (version files, code changes)
- Preserved Rust 2024 edition fixes (unsafe extern blocks)
- Kept all new Frida 17.10+ APIs (attach_with_options, instrumentation options)
- Fixed unsafe block placement in memory_access_monitor.rs
- Updated FRIDA_VERSION to 17.15.4
- Fixed elf_module.rs copyright attribution

All clippy and build checks passing.
kkuehl added 6 commits July 18, 2026 12:55
Add comprehensive kernel-mode memory operations:

- Kernel module enumeration
- Kernel memory read/write
- Kernel memory range enumeration
- Kernel page allocation/deallocation
- Kernel memory protection changes
- Pattern-based kernel memory scanning

All kernel APIs are unsafe and require appropriate privileges.
Closes gap in kernel functionality (100% missing → fully implemented).
Document all changes, new features, and remaining gaps:
- Breaking changes (removed page allocation APIs)
- New features (Darwin modules, Kernel APIs)
- API coverage analysis by category
- Notable missing APIs with priorities
- Comparison with other language bindings
- Recommendations for reaching parity

Current status: ~50% coverage, target ~80% for parity with other bindings.
Add new instructions from Frida 17.16.1:

x86_64 Writer (AVX-512):
- kmovq (k-register mask operations)
- vextracti64x4 (extract 256-bit from 512-bit ZMM)
- vinserti64x4 (insert 256-bit into 512-bit ZMM)
- vmovdqu64 (unaligned 512-bit move)

ARM64 Writer:
- movk (move with keep for building 64-bit constants)
- pacia (Pointer Authentication Code for ARMv8.3-A)

Note: Memory::allocate/allocate_near already existed, no changes needed.
- Added AVX-512 x86_64 instructions (+6)
- Added ARM64 PAC/MOVK instructions (+2)
- Memory allocate APIs already existed
- Updated coverage: ~52% overall
- x86_64 Writer: 88% → 92%
- ARM64 Writer: 30% → 32%
- Memory: 85% → 100%
Add 25 new ARM64 instructions:
- Branch/control: ret, br, blr, b_imm, b_label, bl_label, cbz, cbnz, tbz, tbnz
- PAC variants: br_reg_no_auth, blr_reg_no_auth
- Stack: push, pop, push_all_x_registers, pop_all_x_registers, push_all_q_registers, pop_all_q_registers
- Load/Store: ldr (reg/u32/u64), str, ldp, stp
- Arithmetic: mov, add, sub, and
- Condition flags: mov_reg_nzcv, mov_nzcv_reg

ARM64 Writer: 23 → 48 instructions (32% → 68% coverage)
@kkuehl kkuehl changed the title Upgrade Frida to 17.15.3, migrate to Rust edition 2024, and expand Gum API coverage Upgrade Frida to 17.16.1 migrate to Rust edition 2024, and expand Gum API coverage Jul 18, 2026
kkuehl added 16 commits July 18, 2026 16:09
- Add devkit download step to docs build job (bindgen needs headers)
- Fix iOS GLib symbol imports (uses bare g_* not _frida_g_*)
- Remove non-existent Darwin module accessor functions
- Use glib_compat::g_free in kernel.rs instead of gum_sys::g_free
The types (GumInterceptorScenario, GumRelocationPolicy, GumAttachOptions, etc.)
DO exist in Frida 17.16.1 devkit headers. Previous CI failures were due to
missing devkit download in docs job (now fixed).
build.rs expects headers in frida-gum-sys/include/ when DOCS_RS=1.
Extract devkit tarball to that location.
The committed header is used for docs builds and needs to be kept in sync
with FRIDA_VERSION. Updated from old version to 17.16.1 to include new types
like GumInterceptorScenario, GumRelocationPolicy, GumAttachOptions, etc.
cargo fmt fixed formatting issues in darwin_module.rs and kernel.rs
Removed 14 duplicate function definitions in Aarch64InstructionWriter:
- put_br_reg, put_b_label, put_push_reg_reg, put_pop_reg_reg
- put_ldr_reg_address, put_ldr_reg_u64, put_ldr_reg_reg_offset
- put_str_reg_reg_offset, put_ldp_reg_reg_reg_offset
- put_stp_reg_reg_reg_offset, put_mov_reg_reg
- put_add_reg_reg_imm, put_add_reg_reg_reg, put_sub_reg_reg_imm

These functions were defined twice - once in the existing codebase
(lines 88-256) and again in my additions for 17.16.1 (lines 353+).
Kept the original definitions and removed duplicates from my additions.

New functions like put_br_reg_no_auth, put_blr_reg, put_cbz_reg_imm,
etc. are retained as they don't have duplicates.
x86_64 writer:
- Use .try_into().unwrap() for GumArgType and GumCallingConvention enums
  (they're i32 on Windows, u32 on macOS - cast needed for cross-platform)

darwin_module (macOS-specific):
- Cast protection field from i32 to u32
- Use .as_ptr() for array fields (segment_name, section_name)
- Access nested offset field via __bindgen_anon_1.__bindgen_anon_1.offset
- Cast library_ordinal (i32 → i16) and symbol_flags (u8 → i8)
- Add new parameters to gum_darwin_module_new_from_file/memory:
  GUM_CPU_INVALID, GUM_PTRAUTH_INVALID, 0 (API changed in 17.16.1)
- Fix segments field access - it's now *mut GArray, not embedded GArray

aarch64 writer:
- Fix put_movk_reg_imm parameter order: (reg, shift: u16, imm: u32)
  (was incorrectly (reg, imm: u32, shift: u8))

kernel.rs:
- Cast CString pointer to *const c_char for gum_kernel_enumerate_module_ranges
  (cstr_core produces *const u8, but iOS expects *const i8)
- Remove underscore prefix from GumCpuType and GumPtrauthSupport constants
  (bindgen generates GumCpuType_GUM_CPU_INVALID, not _GumCpuType_GUM_CPU_INVALID)
- Apply cargo fmt to x86_64 writer (break long lines)
Instead of .try_into().unwrap(), use 'as u32' cast which works on both:
- Windows: enums are i32, cast to u32
- Linux/macOS: enums are u32, no-op cast

This is the idiomatic Rust solution for platform-dependent enum types.
Windows: enums are i32, need cast to u32
Linux/macOS: enums are u32, no cast needed

Applied to all functions using:
- _GumArgType_GUM_ARG_REGISTER
- _GumArgType_GUM_ARG_ADDRESS
- _GumCallingConvention_GUM_CALL_CAPI

This eliminates clippy warnings on Linux while maintaining correctness on Windows.
- Import InstructionWriter trait (needed for ::new())
- Import Aarch64Register from correct path
- Combine imports on one line
On 32-bit platforms (i686), gsize is u32, not u64.
Changed all size/offset casts from 'as u64' to 'as gum_sys::gsize':

- memory.rs: n_read variable, gum_memory_write len, gum_memory_find_pointers values
- code_allocator.rs: slice_size, alignment, max_distance
- code_segment.rs: size, source_offset, source_size, max_distance
- thread.rs: watchpoint size

This fixes compilation on i686-unknown-linux-gnu target.
@kkuehl
kkuehl force-pushed the kkuehl/frida-rust-updates branch 2 times, most recently from d7b4a60 to a8fd0c7 Compare July 18, 2026 22:20
@kkuehl
kkuehl marked this pull request as ready for review July 18, 2026 22:21
@s1341

s1341 commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

I really don't love these omnibus PRs. they are really hard to review.

@kkuehl

kkuehl commented Jul 19, 2026 via email

Copy link
Copy Markdown
Contributor Author

@kkuehl kkuehl closed this Jul 19, 2026
@s1341

s1341 commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Ok. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants